home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Scope / Scope Disk #048 (199x)(Scope PD)(US)[WB].zip / Scope Disk #048 (199x)(Scope PD)(US)[WB].adf / ShowFont32 / showfont.c < prev    next >
C/C++ Source or Header  |  1989-01-02  |  33KB  |  1,109 lines

  1. /********************************************/
  2. /*   ShowFont 3.2 - by Arthur Johnson Jr.   */
  3. /* ======================================== */
  4. /* Usage: ShowFont [font_name] [font_size]  */
  5. /* ======================================== */
  6. /*      Last modifications - 12/20/88       */
  7. /********************************************/
  8.  
  9. #include "intuition/intuition.h" /* this one includes heaps o' stuff */
  10. #include "exec/memory.h"
  11. #include "libraries/diskfont.h"
  12.  
  13. #define XAREA       20      /* no characters beyond (screenwidth - XAREA) */
  14. #define FONTBUFFER  5000    /* hopefully enough for most people */
  15. #define FONTNAMELEN 30      /* maximum font name length */
  16. #define MAXFLAGS    9       /* total of nine style flags so far */
  17.  
  18. #define MAXDISPLAY  7       /* max names, sizes, and styles to display */
  19. #define NAMELEN     13      /* maximum chars of name displayed */
  20. #define NAMEXPOS    13
  21. #define SIZEXPOS    145
  22. #define STYLXPOS    197
  23. #define TOPYPOS     7
  24.  
  25. #define BASELINE    6   /* for Topaz-8 font */
  26. #define YINCR       8
  27.  
  28. /* these are short little macro expanders to save me some typing effort */
  29. #define SIZES       fonts[namesel].sizes
  30. #define SIZESEL     fonts[namesel].sizesel
  31. #define STYLES      fonts[namesel].size[SIZESEL].styles
  32. #define STYLE       fonts[namesel].size[SIZESEL].style
  33. #define STYLESEL    fonts[namesel].size[SIZESEL].stylesel
  34.  
  35. extern struct NewScreen newscreen;
  36. extern struct Gadget W_Prop;
  37. extern struct Menu Menu1;
  38. extern struct NewWindow newwindow;
  39. extern struct Requester requester1;
  40. extern struct Requester requester2;
  41. extern struct PropInfo W_PropSInfo;
  42. extern struct PropInfo R_FontSInfo;
  43. extern struct PropInfo R_SizeSInfo;
  44. extern struct PropInfo R_StyleSInfo;
  45. extern struct Gadget R_Font;
  46. extern struct Gadget R_Size;
  47. extern struct Gadget R_Style;
  48. extern struct Border Outline1;
  49.  
  50. struct Screen *screen;
  51. struct Window *window;
  52. struct RastPort *rp;
  53. struct Gadget *whichgad;
  54. struct IntuiMessage *message;
  55.  
  56. struct IntuitionBase *IntuitionBase;
  57. struct GfxBase *GfxBase;
  58. struct DiskfontBase *DiskfontBase;
  59.  
  60. struct sizenode {
  61.     UWORD ysize;
  62.     int   styles;
  63.     UBYTE style[MAXFLAGS];
  64.     UBYTE flags;
  65.     int   stylesel;
  66. };
  67.  
  68. struct tempsizenode {
  69.     UWORD ysize;
  70.     int   styles;
  71.     UBYTE style[MAXFLAGS];
  72.     UBYTE flags;
  73.     struct tempsizenode *prev;
  74.     struct tempsizenode *next;
  75. };
  76.  
  77. struct fontinfo {
  78.     char    name[FONTNAMELEN + 1];
  79.     int     sizes;
  80.     struct  sizenode *size;
  81.     int     sizesel;
  82. };
  83. struct fontinfo *fonts;
  84.  
  85. struct tempfontinfo {
  86.     char    name[FONTNAMELEN + 1];
  87.     int     sizes;
  88.     struct  tempsizenode *size;
  89.     struct  tempfontinfo *prev;
  90.     struct  tempfontinfo *next;
  91. };
  92. struct tempfontinfo *tempfonts;
  93.  
  94. char fontname[FONTNAMELEN + 6]; /* include space for '.font\0' */
  95. struct TextAttr myfont = { /* necessary structure for fonts */
  96.     &fontname[0],   /* default is Topaz-8 fault */
  97.     8,
  98.     FS_NORMAL,
  99.     FPF_ROMFONT };
  100. struct TextFont *font;
  101.  
  102. struct {
  103.     UBYTE *string;
  104.     int length;
  105. } fontline[256];    /* maximum of 256 lines (one char/line) */
  106.  
  107. /* I just don't want to pass the following values around */
  108.  
  109. int numfonts;
  110.  
  111. int screenwidth, screenheight;
  112.  
  113. int nameline, sizeline, styleline,
  114.     namesel,
  115.     rfontlastline, rsizelastline, rstylelastline;
  116.  
  117. USHORT fontpropsize, fontproppos, sizepropsize, sizeproppos,
  118.         stylepropsize, styleproppos;
  119.  
  120. void clearfonts()
  121. {
  122.  
  123.     register i;
  124.  
  125.     for (i = 0; i < numfonts; i++)
  126.         FreeMem(fonts[i].size, fonts[i].sizes * sizeof(struct sizenode));
  127.     FreeMem(fonts, numfonts * sizeof(struct fontinfo));
  128.  
  129.     numfonts = 0;   /* there are no fonts */
  130.  
  131. }
  132.  
  133. void clearfontlines()
  134. {
  135.  
  136.     register i = 0;
  137.  
  138.     while (fontline[i].length != 0) {
  139.         FreeMem(fontline[i].string, fontline[i].length);
  140.         fontline[i].length = 0;
  141.         ++i;
  142.     }
  143.  
  144. }
  145.  
  146. void cleanup(text)
  147. char *text;
  148. {
  149.  
  150.     clearfontlines();
  151.     clearfonts();
  152.     if (font)
  153.         CloseFont(font);
  154.     if (window) {
  155.         ClearMenuStrip(window);
  156.         CloseWindow(window);
  157.     }
  158.     if (screen)
  159.         CloseScreen(screen);
  160.     if (DiskfontBase)
  161.         CloseLibrary(DiskfontBase);
  162.     if (IntuitionBase)
  163.         CloseLibrary(IntuitionBase);
  164.     if (GfxBase)
  165.         CloseLibrary(GfxBase);
  166.  
  167.     if (text)
  168.         puts(text);
  169.  
  170.     exit(0);
  171.  
  172. }
  173.  
  174. void cleartempsize(font)
  175. struct tempfontinfo *font;
  176. {
  177.  
  178.     struct tempsizenode *erase;
  179.  
  180.     while (font->size != NULL) {
  181.         erase = font->size;
  182.         font->size = font->size->next;
  183.         FreeMem(erase, sizeof(struct tempsizenode));
  184.     }
  185.  
  186. }
  187.  
  188. void cleartempfonts()
  189. {
  190.  
  191.     struct tempfontinfo *erase;
  192.  
  193.     while (tempfonts != NULL) {
  194.         erase = tempfonts;
  195.         tempfonts = tempfonts->next;
  196.         cleartempsize(erase);
  197.         FreeMem(erase, sizeof(struct tempfontinfo));
  198.     }
  199.  
  200. }
  201.  
  202. int stylenum(style)
  203. UBYTE style;
  204. {
  205.  
  206.     if (style == FS_NORMAL)
  207.         return(0);
  208.     if (style & FSF_UNDERLINED)
  209.         return(1);
  210.     if (style & FSF_BOLD)
  211.         return(2);
  212.     if (style & FSF_ITALIC)
  213.         return(4);
  214.     if (style & FSF_EXTENDED)
  215.         return(8);
  216.  
  217. }
  218.  
  219. void addsizenode(font, ysize, style, flags)
  220. struct tempfontinfo *font;
  221. UWORD ysize;
  222. UBYTE style;
  223. UBYTE flags;
  224. {
  225.  
  226.     struct tempsizenode *search, *prev, *newnode;
  227.  
  228.     int foundit = FALSE;
  229.  
  230.     prev = NULL;
  231.     search = font->size;
  232.     while (search != NULL) {
  233.         if ((search->ysize == ysize) && (search->flags == flags)) {
  234.             search->style[search->styles] = stylenum(style);
  235.             ++(search->styles);
  236.             foundit = TRUE;
  237.             break;
  238.         }
  239.         else {
  240.             if (search->ysize >= ysize) /* should go before this size */
  241.                 break;
  242.             else {
  243.                 prev = search;
  244.                 search = search->next;
  245.             }
  246.         }
  247.     }
  248.     if (!foundit) {
  249.         newnode = (struct tempsizenode *)AllocMem(sizeof(struct tempsizenode), MEMF_CLEAR);
  250.         if (newnode == NULL)
  251.             cleanup("ShowFont: couldn't allocate enough memory!");
  252.         newnode->ysize = ysize;
  253.         newnode->styles = 0;
  254.         newnode->flags = flags;
  255.         newnode->style[newnode->styles] = stylenum(style);
  256.         ++(newnode->styles);
  257.         ++(font->sizes);
  258.         if (font->size == NULL) {   /* list is empty */
  259.             newnode->prev = NULL;
  260.             newnode->next = NULL;
  261.             font->size = newnode;
  262.         }
  263.         else {
  264.             if (search == NULL) {   /* add at end o' list */
  265.                 prev->next = newnode;
  266.                 newnode->prev = prev;
  267.                 newnode->next = NULL;
  268.             }
  269.             else {
  270.                 if (search->prev == NULL) { /* add at beginning o' list */
  271.                     newnode->prev = NULL;
  272.                     newnode->next = search;
  273.                     search->prev = newnode;
  274.                     font->size = newnode;
  275.                 }
  276.                 else {  /* add in the middle o' the list */
  277.                     search->prev->next = newnode;
  278.                     newnode->prev = search->prev;
  279.                     newnode->next = search;
  280.                     search->prev = newnode;
  281.                 }
  282.             }
  283.         }
  284.     }
  285.  
  286. }
  287.  
  288. void readfonts()
  289. {
  290.  
  291.     struct AvailFontsHeader *afh;
  292.     struct AvailFonts *af;
  293.  
  294.     struct tempfontinfo *search, *prev, *newnode;
  295.     struct tempsizenode *sizenode;
  296.  
  297.     int foundit;
  298.  
  299.     int mem = FONTBUFFER,
  300.         moremem;
  301.  
  302.     register i, j, k;
  303.  
  304.     clearfonts();
  305.  
  306.     do {
  307.         afh = (struct AvailFontsHeader *)AllocMem(mem, MEMF_CLEAR);
  308.         if (afh == NULL)
  309.             cleanup("ShowFont: couldn't allocate enough memory!");
  310.         moremem = AvailFonts(afh, mem, 0xFF);
  311.         if (moremem != 0) {
  312.             FreeMem(afh, mem);
  313.             mem += moremem;
  314.             printf("ShowFont: allocating %d bytes of memory for the FONTS: info.\n", mem);
  315.         }
  316.     } while (moremem != 0);
  317.  
  318.     if (afh->afh_NumEntries == 0) {
  319.         FreeMem(afh, mem);
  320.         cleanup("ShowFont: couldn't find any fonts! (Is FONTS: set correctly?)");
  321.     }
  322.  
  323.     tempfonts = NULL;
  324.  
  325.     af = (struct AvailFonts *)&afh[1];
  326.     for (i = 0; i < afh->afh_NumEntries; i++) {
  327.         if (!((af->af_Attr.ta_Flags & FPF_REMOVED) ||
  328.             (af->af_Attr.ta_Flags & FPF_REVPATH) ||
  329.             ((af->af_Type & AFF_MEMORY) &&
  330.              (af->af_Attr.ta_Flags & FPF_DISKFONT)))) {
  331.  
  332.             prev = NULL;
  333.             search = tempfonts;
  334.             foundit = FALSE;
  335.             while (search != NULL) {
  336.                 if (strnicmp(af->af_Attr.ta_Name, search->name, (strlen(af->af_Attr.ta_Name) - 5)) == NULL) {
  337.                     addsizenode(search, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  338.                     foundit = TRUE;
  339.                     break;
  340.                 }
  341.                 else {
  342.                     if (strnicmp(af->af_Attr.ta_Name, search->name, (strlen(af->af_Attr.ta_Name) - 5)) < NULL)
  343.                         break;  /* should go before here */
  344.                     else {
  345.                         prev = search;
  346.                         search = search->next;
  347.                     }
  348.                 }
  349.             }
  350.             if (!foundit) {
  351.                 newnode = (struct tempfontinfo *)AllocMem(sizeof(struct tempfontinfo), MEMF_CLEAR);
  352.                 if (newnode == NULL)
  353.                     cleanup("ShowFont: couldn't allocate enough memory!");
  354.                 stccpy(newnode->name, af->af_Attr.ta_Name, (strlen(af->af_Attr.ta_Name) - 4));
  355.                 newnode->sizes = 0;
  356.                 newnode->size = NULL;
  357.                 addsizenode(newnode, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  358.                 ++numfonts;
  359.                 if (tempfonts == NULL) { /* list is empty */
  360.                     newnode->prev = NULL;
  361.                     newnode->next = NULL;
  362.                     tempfonts = newnode;
  363.                 }
  364.                 else {
  365.                     if (search == NULL) {   /* should add at end */
  366.                         prev->next = newnode;
  367.                         newnode->prev = prev;
  368.                         newnode->next = NULL;
  369.                     }
  370.                     else {
  371.                         if (search->prev == NULL) { /* add at beginning */
  372.                             newnode->prev = NULL;
  373.                             newnode->next = search;
  374.                             search->prev = newnode;
  375.                             tempfonts = newnode;
  376.                         }
  377.                         else { /* add in the middle o' the list */
  378.                             search->prev->next = newnode;
  379.                             newnode->prev = search->prev;
  380.                             newnode->next = search;
  381.                             search->prev = newnode;
  382.                         }
  383.                     }
  384.                 }
  385.             }
  386.         }
  387.         af++;
  388.     }
  389.  
  390.     FreeMem(afh, mem);
  391.  
  392.     if ((fonts = (struct fontinfo *)AllocMem(numfonts * sizeof(struct fontinfo), MEMF_CLEAR)) == NULL)
  393.         cleanup("ShowFont: couldn't allocate secondary memory!");
  394.  
  395.     search = tempfonts;
  396.  
  397.     for (i = 0; i < numfonts; i++) {
  398.         strcpy(fonts[i].name, search->name);
  399.         fonts[i].sizes = search->sizes;
  400.         if ((fonts[i].size = (struct sizenode *)AllocMem(fonts[i].sizes * sizeof(struct sizenode), MEMF_CLEAR)) == NULL)
  401.             cleanup("ShowFont: couldn't allocate tertiary memory!");
  402.         sizenode = search->size;
  403.         for (j = 0; j < fonts[i].sizes; j++) {
  404.             fonts[i].size[j].ysize = sizenode->ysize;
  405.             fonts[i].size[j].styles = sizenode->styles;
  406.             for (k = 0; k < fonts[i].size[j].styles; k++)
  407.                 fonts[i].size[j].style[k] = sizenode->style[k];
  408.             fonts[i].size[j].stylesel = 0;
  409.             fonts[i].size[j].flags = sizenode->flags;
  410.             sizenode = sizenode->next;
  411.         }
  412.         fonts[i].sizesel = 0;
  413.         search = search->next;
  414.     }
  415.  
  416.     cleartempfonts();
  417.  
  418. }
  419.  
  420. void setupscreen()
  421. {
  422.  
  423.     if (window) {
  424.         ClearMenuStrip(window);
  425.         CloseWindow(window);
  426.     }
  427.     if (screen)
  428.         CloseScreen(screen);
  429.  
  430.     newscreen.Width = screenwidth;
  431.     newscreen.Height = screenheight;
  432.     if (screenwidth == 320)
  433.         if (screenheight == 200)
  434.             newscreen.ViewModes = NULL;
  435.         else
  436.             newscreen.ViewModes = LACE;
  437.     else
  438.         if (screenheight == 200)
  439.             newscreen.ViewModes = HIRES;
  440.         else
  441.             newscreen.ViewModes = HIRES | LACE;
  442.  
  443.     newwindow.Width = screenwidth;
  444.     newwindow.Height = screenheight;
  445.  
  446.     if (screenwidth == 320) {
  447.         requester1.LeftEdge = 0;
  448.         requester2.LeftEdge = 56;
  449.     }
  450.     else {
  451.         requester1.LeftEdge = 160;
  452.         requester2.LeftEdge = 216;
  453.     }
  454.  
  455.     if (screenheight == 200) {
  456.         requester1.TopEdge = 50;
  457.         requester2.TopEdge = 50;
  458.     }
  459.     else {
  460.         requester1.TopEdge = 150;
  461.         requester2.TopEdge = 150;
  462.     }
  463.  
  464.     if ((screen = (struct Screen *)OpenScreen(&newscreen)) == NULL)
  465.         cleanup("ShowFont: couldn't open the screen.");
  466.     newwindow.Screen = screen;
  467.  
  468.     if ((window = (struct Window *)OpenWindow(&newwindow)) == NULL)
  469.         cleanup("ShowFont: couldn't open the window.");
  470.     rp = window->RPort;
  471.  
  472.     SetMenuStrip(window, &Menu1);
  473.  
  474. }
  475.  
  476. int findfont()
  477. {
  478.  
  479.     int low, mid, high;
  480.  
  481.     low = 0;
  482.     high = numfonts - 1;
  483.     while (low <= high) {
  484.         mid = (low + high) / 2;
  485.         if (strnicmp(fontname, fonts[mid].name, (strlen(fontname) - 5)) < 0)
  486.             high = mid - 1;
  487.         else
  488.             if (strnicmp(fontname, fonts[mid].name, (strlen(fontname) - 5)) > 0)
  489.                 low = mid + 1;
  490.             else
  491.                 return(mid);
  492.     }
  493.  
  494.     return(-1);
  495.  
  496. }
  497.  
  498. USHORT proppos(line, maxline)
  499. int line;
  500. int maxline;
  501. {
  502.  
  503.     if (maxline == 1)
  504.         return((USHORT)MAXBODY);
  505.     else
  506.         return((USHORT)((MAXBODY * (line - 1)) / (maxline - 1)));
  507.  
  508. }
  509.  
  510. USHORT propsize(display, maxdisplay)
  511. int display;
  512. int maxdisplay;
  513. {
  514.  
  515.     if (display >= maxdisplay)
  516.         return((USHORT)MAXPOT);
  517.     else
  518.         return((USHORT)((MAXPOT * display) / maxdisplay));
  519.  
  520. }
  521.  
  522. int propline(proppos, maxline)
  523. USHORT proppos;
  524. int maxline;
  525. {
  526.  
  527.     return((proppos * maxline) / MAXPOT);
  528.  
  529. }
  530.  
  531. void refresh1(rp)
  532. struct RastPort *rp;
  533. {
  534.  
  535.     register loop,
  536.              x = NAMEXPOS,
  537.              y = TOPYPOS + BASELINE;
  538.  
  539.     char namestring[NAMELEN + 1];
  540.  
  541.     SetDrMd(rp, JAM2);
  542.     SetAPen(rp, 1);
  543.  
  544.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  545.         Move(rp, x, y);
  546.         SetBPen(rp, 0);
  547.         if ((nameline + loop) < numfonts) {
  548.             if ((nameline + loop) == namesel)
  549.                 SetBPen(rp, 2);
  550.             sprintf(namestring, "%-13s", fonts[nameline + loop].name);
  551.             Text(rp, namestring, NAMELEN);
  552.         }
  553.         else
  554.             Text(rp, "             ", NAMELEN);
  555.         y += YINCR;
  556.     }
  557.  
  558. }
  559.  
  560. void refresh2(rp)
  561. struct RastPort *rp;
  562. {
  563.  
  564.     register loop,
  565.              x = SIZEXPOS,
  566.              y = TOPYPOS + BASELINE;
  567.  
  568.     char sizestring[3 + 1];
  569.  
  570.     SetDrMd(rp, JAM2);
  571.  
  572.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  573.         Move(rp, x, y);
  574.         SetBPen(rp, 0);
  575.         if ((sizeline + loop) < SIZES) {
  576.             SetAPen(rp, 1);
  577.             if (fonts[namesel].size[sizeline + loop].flags & FPF_PROPORTIONAL)
  578.                 SetAPen(rp, 3);
  579.             if ((sizeline + loop) == SIZESEL)
  580.                 SetBPen(rp, 2);
  581.             sprintf(sizestring, "%3d", fonts[namesel].size[sizeline + loop].ysize);
  582.             Text(rp, sizestring, 3);
  583.         }
  584.         else
  585.             Text(rp, "   ", 3);
  586.         y += YINCR;
  587.     }
  588.  
  589. }
  590.  
  591. void refresh3(rp)
  592. struct RastPort *rp;
  593. {
  594.  
  595.     register x = STYLXPOS,
  596.              y = TOPYPOS + BASELINE,
  597.              loop;
  598.  
  599.     SetDrMd(rp, JAM2);
  600.     SetAPen(rp, 1);
  601.  
  602.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  603.         Move(rp, x, y);
  604.         if ((loop + styleline) == STYLESEL)
  605.             SetBPen(rp, 2);
  606.         else
  607.             SetBPen(rp, 0);
  608.         if ((loop + styleline) < STYLES) {
  609.             switch(STYLE[(loop + styleline)]) {
  610.                 case 0: Text(rp, "Normal      ", 12);
  611.                         break;
  612.                 case 1: Text(rp, "Underlined  ", 12);
  613.                         break;
  614.                 case 2: Text(rp, "Bold        ", 12);
  615.                         break;
  616.                 case 4: Text(rp, "Italic      ", 12);
  617.                         break;
  618.                 case 8: Text(rp, "Extended    ", 12);
  619.                         break;
  620.             }
  621.         }
  622.         else
  623.             Text(rp, "            ", 12);
  624.         y += YINCR;
  625.     }
  626.  
  627. }
  628.  
  629. void updateprop(prop, requester, proppos, propsize)
  630. struct Gadget *prop;
  631. struct Requester *requester;
  632. USHORT proppos;
  633. USHORT propsize;
  634. {
  635.  
  636.     NewModifyProp(prop, window, requester, AUTOKNOB | FREEVERT, -1, proppos, -1, propsize, 1);
  637.  
  638. }
  639.  
  640. /* updatetype =  1 : refresh 1      */
  641. /*                   update 2, 3    */
  642. /*                   refresh 2, 3   */
  643. /*               2 : refresh 2      */
  644. /*                   update 3       */
  645. /*                   refresh 3      */
  646. /*               3 : refresh 3      */
  647. /*              10 : arrow 1, u/r 1 */
  648. /*              20 : arrow 2, u/r 2 */
  649. /*              30 : arrow 3, u/r 3 */
  650. void duhprop(rp, updatetype)
  651. struct RastPort *rp;
  652. int updatetype;
  653. {
  654.  
  655.     if (updatetype == 1) {
  656.         rsizelastline = (SIZES - MAXDISPLAY) + 1;
  657.         if (rsizelastline < 1)
  658.             rsizelastline = 1;
  659.         sizeline = SIZESEL;
  660.         if ((sizeline + 1) >= rsizelastline)
  661.             sizeline = rsizelastline - 1;
  662.         sizepropsize = propsize(MAXDISPLAY, SIZES);
  663.         sizeproppos = proppos((sizeline + 1), rsizelastline);
  664.     }
  665.     if (updatetype <= 3) {
  666.         rstylelastline = (STYLES - MAXDISPLAY) + 1;
  667.         if (rstylelastline < 1)
  668.             rstylelastline = 1;
  669.         styleline = STYLESEL;
  670.         if ((styleline + 1) >= rstylelastline)
  671.             styleline = rstylelastline - 1;
  672.         stylepropsize = propsize(MAXDISPLAY, STYLES);
  673.         styleproppos = proppos((styleline + 1), rstylelastline);
  674.     }
  675.  
  676.     switch (updatetype) {
  677.          case 10: fontproppos = proppos((nameline + 1), rfontlastline);
  678.                   break;
  679.          case 20: sizeproppos = proppos((sizeline + 1), rsizelastline);
  680.                   break;
  681.          case 30: styleproppos = proppos((styleline + 1), rstylelastline);
  682.                   break;
  683.     }
  684.  
  685.     switch (updatetype) {
  686.         case  1: refresh1(rp);
  687.                  updateprop(&R_Size, &requester1, sizeproppos, sizepropsize);
  688.                  updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  689.                  refresh2(rp);
  690.                  refresh3(rp);
  691.                  break;
  692.         case  2: refresh2(rp);
  693.                  updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  694.                  refresh3(rp);
  695.                  break;
  696.         case  3: refresh3(rp);
  697.                  break;
  698.         case 10: updateprop(&R_Font, &requester1, fontproppos, fontpropsize);
  699.                  refresh1(rp);
  700.                  break;
  701.         case 20: updateprop(&R_Size, &requester1, sizeproppos, sizepropsize);
  702.                  refresh2(rp);
  703.                  break;
  704.         case 30: updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  705.                  refresh3(rp);
  706.                  break;
  707.     }
  708.  
  709. }
  710.  
  711. int selectfont()
  712. {
  713.  
  714.     struct RastPort *rp;
  715.  
  716.     int returnvalue,
  717.         refreshhow,
  718.         x, y;
  719.  
  720.     ULONG  class;
  721.  
  722.     Request(&requester1, window);
  723.     rp = requester1.ReqLayer->rp;
  724.  
  725.     namesel = findfont();
  726.  
  727.     rfontlastline = numfonts - MAXDISPLAY + 1;
  728.     if (rfontlastline < 1)
  729.         rfontlastline = 1;
  730.     fontpropsize = propsize(MAXDISPLAY, numfonts);
  731.  
  732.     nameline = namesel;
  733.     if ((nameline + 1) >= rfontlastline)
  734.         nameline = rfontlastline - 1;
  735.  
  736.     duhprop(rp, 1);
  737.     duhprop(rp, 10);
  738.  
  739.     DrawBorder(rp, &Outline1, 0, 0);
  740.  
  741.     refreshhow = 0;
  742.     returnvalue = 0;
  743.  
  744.     while (returnvalue == 0) {
  745.         switch (refreshhow) {
  746.             case  1: if (nameline > 0)
  747.                          --nameline;
  748.                      duhprop(rp, 10);
  749.                      break;
  750.             case  2: nameline = propline(R_FontSInfo.VertPot, rfontlastline);
  751.                      if ((nameline + 1) >= rfontlastline)
  752.                          nameline = rfontlastline - 1;
  753.                      refresh1(rp);
  754.                      break;
  755.             case  3: if ((nameline + 1) < rfontlastline)
  756.                          ++nameline;
  757.                      duhprop(rp, 10);
  758.                      break;
  759.             case  4: if (sizeline > 0)
  760.                          --sizeline;
  761.                      duhprop(rp, 20);
  762.                      break;
  763.             case  5: sizeline = propline(R_SizeSInfo.VertPot, rsizelastline);
  764.                      if ((sizeline + 1) >= rsizelastline)
  765.                          sizeline = rsizelastline - 1;
  766.                      refresh2(rp);
  767.                      break;
  768.             case  6: if ((sizeline + 1) < rsizelastline)
  769.                          ++sizeline;
  770.                      duhprop(rp, 20);
  771.                      break;
  772.             case  7: if (styleline > 0)
  773.                          --styleline;
  774.                      duhprop(rp, 30);
  775.                      break;
  776.             case  8: styleline = propline(R_StyleSInfo.VertPot, rstylelastline);
  777.                      if ((styleline + 1) >= rstylelastline)
  778.                          styleline = rstylelastline - 1;
  779.                      refresh3(rp);
  780.                      break;
  781.             case  9: if ((styleline + 1) < rstylelastline)
  782.                          ++styleline;
  783.                      duhprop(rp, 30);
  784.                      break;
  785.         }
  786.  
  787.         message = (struct IntuiMessage *)GetMsg(window->UserPort);
  788.         if (message != 0) {
  789.             class = message->Class;
  790.             x = message->MouseX - requester1.LeftEdge;
  791.             y = message->MouseY - requester1.TopEdge;
  792.             whichgad = (struct Gadget *)message->IAddress;
  793.             ReplyMsg(message);
  794.  
  795.             if (class == GADGETDOWN) {
  796.                 refreshhow = whichgad->GadgetID;
  797.             }
  798.             if (class == GADGETUP) {
  799.                 switch (whichgad->GadgetID) {
  800.                     case 101: returnvalue = 1;
  801.                               break;
  802.                     case 102: returnvalue = -1;
  803.                               break;
  804.                 }
  805.                 refreshhow = 0; /* no more auto-scrolling */
  806.             }
  807.             if (class == MOUSEBUTTONS) {
  808.                 if ((y >= 0) && (y < 100) && (x >= 0) && (x < 320)) {
  809.                     y -= TOPYPOS;
  810.                     y = y / YINCR;
  811.                     if (y < MAXDISPLAY) {
  812.                         if ((x >= NAMEXPOS) && (x < (NAMEXPOS + NAMELEN * 8))) {
  813.                             if (namesel == (nameline + y)) {
  814.                                 returnvalue = 1;
  815.                                 EndRequest(&requester1, window);
  816.                             }
  817.                             else {
  818.                                 namesel = nameline + y;
  819.                                 if (namesel >= numfonts)
  820.                                     namesel = numfonts - 1;
  821.                                 duhprop(rp, 1);
  822.                             }
  823.                         }
  824.                         if ((x >= SIZEXPOS) && (x < (SIZEXPOS + 3 * 8))) {
  825.                             if (SIZESEL == (sizeline + y)) {
  826.                                 returnvalue = 1;
  827.                                 EndRequest(&requester1, window);
  828.                             }
  829.                             else {
  830.                                 SIZESEL = sizeline + y;
  831.                                 if (SIZESEL >= SIZES)
  832.                                     SIZESEL = SIZES - 1;
  833.                                 duhprop(rp, 2);
  834.                             }
  835.                         }
  836.                         if ((x >= STYLXPOS) && (x < (STYLXPOS + 12 * 8))) {
  837.                             if (STYLESEL == (styleline + y)) {
  838.                                 returnvalue = 1;
  839.                                 EndRequest(&requester1, window);
  840.                             }
  841.                             else {
  842.                                 STYLESEL = styleline + y;
  843.                                 if (STYLESEL >= STYLES)
  844.                                     STYLESEL = STYLES - 1;
  845.                                 duhprop(rp, 3);
  846.                             }
  847.                         }
  848.                     }
  849.                 }
  850.             }
  851.         }
  852.     }
  853.  
  854.     if (returnvalue == 1) {
  855.         strcpy(fontname, fonts[namesel].name);
  856.         strcat(fontname, ".font");
  857.         myfont.ta_YSize = fonts[namesel].size[SIZESEL].ysize;
  858.         myfont.ta_Style = STYLE[STYLESEL];
  859.         myfont.ta_Flags = fonts[namesel].size[SIZESEL].flags;
  860.     }
  861.  
  862.     return(returnvalue);
  863.  
  864. }
  865.  
  866. void mycat(s, c)
  867. char *s;
  868. char c;
  869. {
  870.  
  871.     while (*s++ != '\0') {}
  872.     *(s - 1) = c;
  873.     *s = '\0';
  874.  
  875. }
  876.  
  877. void main(argc,argv)
  878. int argc;
  879. char *argv[];
  880. {
  881.  
  882.     int cont = TRUE,
  883.         rethinkfont = TRUE;
  884.  
  885.     ULONG   class;
  886.     USHORT  code;
  887.  
  888.     int line, maxline,
  889.         yarea,
  890.         startchar,
  891.         len, pixels,
  892.         whichmenu, whichitem,
  893.         wproplastline,
  894.         refreshhow;
  895.  
  896.     char windowtitle[81];
  897.  
  898.     USHORT numy, pos, size;
  899.  
  900.     register loop, i;
  901.  
  902.     UBYTE textline[256];
  903.  
  904.     if ((argc == 2) && (*argv[1] == '?'))
  905.         cleanup("Usage: ShowFont [font_name] [font_size]");
  906.  
  907.     if ((IntuitionBase = (struct IntuitionBase *)
  908.             OpenLibrary("intuition.library", 0)) == NULL)
  909.         cleanup("ShowFont: couldn't open 'intuition.library'.");
  910.  
  911.     if ((GfxBase = (struct GfxBase *)
  912.             OpenLibrary("graphics.library", 0)) == NULL)
  913.         cleanup("ShowFont: couldn't open 'graphics.library'.");
  914.  
  915.     if ((DiskfontBase = (struct DiskfontBase *)
  916.             OpenLibrary("diskfont.library", 0)) == NULL)
  917.         cleanup("ShowFont: couldn't open 'diskfont.library'.");
  918.  
  919.     screenwidth = 640;
  920.     screenheight = 200;
  921.     setupscreen();
  922.  
  923.     fonts = NULL;
  924.  
  925.     if (argc == 1)
  926.         strcpy(fontname, "Topaz.font");
  927.     else
  928.         sprintf(fontname, "%s.font", argv[1]);
  929.     if (argc < 3) {
  930.         readfonts();
  931.         selectfont();
  932.     }
  933.     else
  934.         myfont.ta_YSize = atoi(argv[2]);
  935.  
  936.     for (i = 0; i < 256; ++i)
  937.         fontline[i].length = 0;
  938.  
  939.     while (cont) {
  940.  
  941.         if (rethinkfont) {
  942.  
  943.             if (font)
  944.                 CloseFont(font);
  945.  
  946.             if ((font = (struct TextFont *)OpenDiskFont(&myfont)) == NULL)
  947.                 cleanup("ShowFont: couldn't find the font.");
  948.  
  949.             if (myfont.ta_YSize > screenheight) {
  950.                 screenheight = 400;
  951.                 setupscreen();
  952.             }
  953.  
  954.             SetFont(rp, font);
  955.  
  956.             clearfontlines();
  957.  
  958.             startchar = font->tf_LoChar;
  959.             line = 0;
  960.             len = 0;
  961.  
  962.             for (loop = font->tf_LoChar; loop <= font->tf_HiChar; ++loop) {
  963.                 textline[len++] = loop;
  964.                 pixels = TextLength(rp, textline, len) + window->BorderLeft;
  965.                 if (pixels > (screenwidth - XAREA)) {
  966.                     --len;
  967.                     fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  968.                     if (fontline[line].string == NULL)
  969.                         cleanup("ShowFont: couldn't allocate enough memory!");
  970.                     for (i = startchar; i < loop; ++i)
  971.                         fontline[line].string[i - startchar] = i;
  972.                     fontline[line].length = len;
  973.                     startchar = loop;
  974.                     ++line;
  975.                     len = 0;
  976.                     --loop; /* must go back and insert that character */
  977.                 }
  978.                 else
  979.                     if (loop == font->tf_HiChar) {
  980.                         fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  981.                         if (fontline[line].string == NULL)
  982.                             cleanup("ShowFont: couldn't allocate enough memory!");
  983.                         for (i = startchar; i <= font->tf_HiChar; ++i)
  984.                             fontline[line].string[i - startchar] = i;
  985.                         fontline[line].length = len;
  986.                         ++line;
  987.                     }
  988.             }
  989.  
  990.             maxline = line;
  991.             line = 0;
  992.             yarea = screenheight - (window->BorderTop + window->BorderBottom);
  993.             numy = yarea / font->tf_YSize;
  994.  
  995.             wproplastline = (maxline - numy) + 1;
  996.             if (wproplastline < 1)
  997.                 wproplastline = 1;
  998.  
  999.             size = propsize(numy, maxline);
  1000.  
  1001.             stccpy(windowtitle, fontname, (strlen(fontname) - 4));
  1002.             sprintf(windowtitle + strlen(windowtitle), " - %d", myfont.ta_YSize);
  1003.             SetWindowTitles(window, windowtitle, -1);
  1004.  
  1005.             rethinkfont = FALSE;
  1006.             refreshhow = 99;    /* refresh it once only */
  1007.         }
  1008.  
  1009.         switch (refreshhow) {
  1010.             case  1: if (line > 0)
  1011.                          --line;
  1012.                      break;
  1013.             case  2: pos = W_PropSInfo.VertPot;
  1014.                      line = propline(pos, wproplastline);
  1015.                      if ((line + 1) > wproplastline)
  1016.                          line = wproplastline - 1;
  1017.                      break;
  1018.             case  3: if ((line + 1) < wproplastline)
  1019.                          ++line;
  1020.                      break;
  1021.         }
  1022.  
  1023.         if (refreshhow != 0) {
  1024.  
  1025.             pos = proppos((line + 1), wproplastline);
  1026.  
  1027.             if (refreshhow != 2)    /* don't blink the slider */
  1028.                 NewModifyProp(&W_Prop, window, NULL, AUTOKNOB | FREEVERT, -1, pos, -1, size, 1);
  1029.  
  1030.             WaitTOF();  /* might just possibly reduce blinking */
  1031.             SetAPen(rp, 0); /* clear the screen */
  1032.             RectFill(rp, window->BorderLeft, window->BorderTop, (screenwidth - XAREA), (screenheight - window->BorderBottom));
  1033.  
  1034.             SetAPen(rp, 1);
  1035.             SetBPen(rp, 0);
  1036.             SetDrMd(rp, JAM2);
  1037.  
  1038.             for (i = line; i < (line + numy); ++i) {
  1039.                 Move(rp, window->BorderLeft, ((i - line) * font->tf_YSize) + window->BorderTop + font->tf_Baseline);
  1040.                 Text(rp, fontline[i].string, fontline[i].length);
  1041.             }
  1042.  
  1043.             if (refreshhow == 99)
  1044.                 refreshhow = 0; /* for initial refreshment only */
  1045.         }
  1046.  
  1047.         message = (struct IntuiMessage *)GetMsg(window->UserPort);
  1048.         if (message != 0) {
  1049.             class = message->Class;
  1050.             code  = message->Code;
  1051.             whichgad = (struct Gadget *)message->IAddress;
  1052.             ReplyMsg(message);
  1053.  
  1054.             if (class == CLOSEWINDOW)
  1055.                 cont = FALSE;
  1056.             if (class == GADGETDOWN)
  1057.                 refreshhow = whichgad->GadgetID;
  1058.             if (class == GADGETUP)
  1059.                 refreshhow = 0; /* stop scrolling */
  1060.             if (class == MENUPICK) {
  1061.                 if (code != MENUNULL) {
  1062.                     whichmenu = MENUNUM(code);
  1063.                     whichitem = ITEMNUM(code);
  1064.                     switch (whichmenu) {
  1065.                         case 0 : switch (whichitem) {
  1066.                                     case 0: Request(&requester2, window); /* about */
  1067.                                             break;
  1068.                                     case 1: cont = FALSE; /* quit */
  1069.                                             break;
  1070.                                  }
  1071.                                  break;
  1072.                         case 1 : switch (whichitem) {
  1073.                                     case 0: if (fonts == NULL)
  1074.                                                 readfonts();
  1075.                                             if (selectfont() == 1)
  1076.                                                 rethinkfont = TRUE;
  1077.                                             break; /* font selection */
  1078.                                  }
  1079.                                  break;
  1080.                         case 2 : switch (whichitem) {
  1081.                                     case 0: screenwidth = 320;
  1082.                                             screenheight = 200;
  1083.                                             setupscreen();
  1084.                                             break;
  1085.                                     case 1: screenwidth = 320;
  1086.                                             screenheight = 400;
  1087.                                             setupscreen();
  1088.                                             break;
  1089.                                     case 2: screenwidth = 640;
  1090.                                             screenheight = 200;
  1091.                                             setupscreen();
  1092.                                             break;
  1093.                                     case 3: screenwidth = 640;
  1094.                                             screenheight = 400;
  1095.                                             setupscreen();
  1096.                                             break;
  1097.                                  }
  1098.                                  rethinkfont = TRUE;
  1099.                                  break;
  1100.                     }
  1101.                 }
  1102.             }
  1103.         }
  1104.     }
  1105.  
  1106.     cleanup(NULL);
  1107.  
  1108. }
  1109.